//-----------------------------------------------------------------------
// <copyright file="FullComponentServices.cs" company="FreeToDev">(c) FreeToDev. This source is subject to the Microsoft Permissive License. See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. All other rights reserved.</copyright>
//-----------------------------------------------------------------------
////namespace FreeToDev.MSBuildTasks.ComponentServices
////{
////    using System;
////    using System.Globalization;
////    using System.IO;
////    using System.Reflection;
////    using COMAdmin;
////    using Microsoft.Build.Framework;
////    using Microsoft.Win32;

////    internal enum CSActivation
////    {
////        /// <summary>
////        /// Inproc
////        /// </summary>
////        Inproc = 0,

////        /// <summary>
////        /// Local
////        /// </summary>
////        Local = 1
////    }

////    /// <summary>
////    /// <b>Valid TaskActions are:</b>
////    /// <para><i>AddComponent</i> (<b>Required: </b>Path, ApplicationName <b>Optional: </b>ActivationString, Identity, Password, EnforceAccessChecks, RunForever, ShutdownAfter)</para>
////    /// <para><i>CheckApplicationExists</i> (<b>Required: </b> ApplicationName <b>Output: </b>Exists)</para>
////    /// <para><i>DeleteApplication</i> (<b>Required: </b>ApplicationName)</para>
////    /// <para><i>RemoveComponent</i> (<b>Required: </b>Path <b>Optional: </b>ApplicationName (for non .net assemblies))</para>
////    /// <para><i>ShutDownApplication</i> (<b>Required: </b>ApplicationName)</para>
////    /// <para><i>UpdateApplication</i> (<b>Required: </b>ApplicationName)</para>
////    /// <para><i>UpdateComponent</i> (<b>Required: </b>ApplicationName, ComponentName, ConstructorString)</para>
////    /// <para><b>Remote Execution Support:</b> No</para>
////    /// </summary>
////    /// <example>
////    /// <code><![CDATA[
////    /// <Project Toolsthis.version="3.5" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
////    ///  <Import Project="..\..\Common\FreeToDev.MSBuild.tasks"/>
////    ///   <Target Name="Default">
////    ///     <FTDComponentServices TaskAction="AddComponent" Path="C:\EntServices.dll" ApplicationName="MyApplication" Identity="Interactive User" Runtime="2.0"/>
////    ///       <FTDComponentServices TaskAction="CheckApplicationExists" ApplicationName="MyApplication" Runtime="2.0">
////    ///           <Output TaskParameter="Exists" PropertyName="DoI"/>
////    ///       </FTDComponentServices>
////    ///       <Message Text="Exists: $(DoI)"/>
////    ///       <FTDComponentServices TaskAction="ShutDownApplication" ApplicationName="MyApplication" Runtime="2.0"/>
////    ///       <FTDComponentServices TaskAction="RemoveComponent" Path="C:\EntServices.dll" ApplicationName="MyApplication" Runtime="2.0"/>
////    ///       <FTDComponentServices TaskAction="DeleteApplication" ApplicationName="MyApplication" OnlyIfExists="true"/>
////    ///   </Target>
////    /// </Project>
////    /// ]]></code>    
////    /// </example>
////    public class FTDComponentServicesFULL : FTDTaskBase
////    {
////        private ShellWrapper shellWrapper;
////        private string runtime = "2.0";
////        private string version = "v2.0.50727";
////        private CSActivation activation = CSActivation.Local;
////        private string pathToFramework;

////        /// <summary>
////        /// Gets whether the application exists.
////        /// </summary>
////        [Output]
////        public bool Exists { get; set; }

////        /// <summary>
////        /// Sets the name of the COM+ component
////        /// </summary>
////        public string ComponentName { get; set; }

////        /// <summary>
////        /// Sets the constructor string for the specified COM+ component.
////        /// </summary>
////        public string ConstructorString { get; set; }

////        /// <summary>
////        /// Sets the name of the COM+ Application.
////        /// </summary>
////        public string ApplicationName { get; set; }

////        /// <summary>
////        /// Sets the description of the COM+ Application.
////        /// </summary>
////        public string ApplicationDescription { get; set; }

////        /// <summary>
////        /// Sets the path to the DLL to be added to the application
////        /// </summary>
////        public string Path { get; set; }

////        /// <summary>
////        /// Sets the process identity for the application. Specify a valid user account or "Interactive User" to have the application assume the identity of the current logged-on user.
////        /// </summary>
////        public string Identity { get; set; }

////        /// <summary>
////        /// Sets the version of the .NET runtime. Defaults to "2.0"
////        /// </summary>
////        public string Runtime
////        {
////            get { return this.runtime; }
////            set { this.runtime = value; }
////        }

////        /// <summary>
////        /// Sets the delay before shutting down a server process after it becomes idle. Shutdown latency ranges from 0 to 1440 minutes (24 hours).
////        /// If RunForever is set to True, this property is ignored.
////        /// ShutdownAfter is not enabled for library (in-process) applications.
////        /// </summary>
////        public string ShutdownAfter { get; set; }

////        /// <summary>
////        /// Sets the type of activation for the application. Defaults to "Local".
////        /// "Local" - local activation indicates that objects within the application run within a dedicated local server process (server application). 
////        /// "Inproc" - in-process activation indicates that objects run in their creator's process (library application). 
////        /// </summary>
////        public string ActivationString { get; set; }

////        /// <summary>
////        /// Sets a value indicating whether whether access checks are performed for the application when clients make calls into it.
////        /// </summary>
////        public bool EnforceAccessChecks { get; set; }

////        /// <summary>
////        /// Sets a value indicating whether a server process can continue if an application is idle.
////        /// If set to True, the server process does not shut down when left idle. If set to False, the process shuts down according to the value set by the ShutdownAfter property.
////        /// RunForever is not enabled for library (in-process) applications.
////        /// </summary>
////        public bool RunForever { get; set; }

////        protected override void InternalExecute()
////        {
////            if (!string.IsNullOrEmpty(this.ActivationString))
////            {
////                this.activation = (CSActivation)Enum.Parse(typeof(CSActivation), this.ActivationString, true);
////            }

////            this.GetPathToFramework();

////            switch (this.TaskAction)
////            {
////                case "AddComponent":
////                    this.AddComponent();
////                    break;
////                case "UpdateComponent":
////                    this.UpdateComponent();
////                    break;
////                case "DeleteApplication":
////                    this.DeleteApplication();
////                    break;
////                case "ShutDownApplication":
////                    this.ShutDownApplication();
////                    break;
////                case "StartApplication":
////                    this.StartApplication();
////                    break;
////                case "UpdateApplication":
////                    this.UpdateApplication();
////                    break;
////                case "CheckApplicationExists":
////                    this.Exists = this.CheckApplicationExists();
////                    break;
////                case "RemoveComponent":
////                    this.RemoveComponent();
////                    break;
////                default:
////                    this.Log.LogError(string.Format(CultureInfo.InvariantCulture, "Invalid TaskAction passed: {0}", this.TaskAction));
////                    return;
////            }
////        }

////        private static COMAdminCatalogCollection GetApplications()
////        {
////            var objAdmin = new COMAdmin.COMAdminCatalog();
////            var objCollection = (COMAdmin.COMAdminCatalogCollection)objAdmin.GetCollection("Applications");
////            objCollection.Populate();
////            return objCollection;
////        }

////        private static bool IsValidAssemblyFile(string path)
////        {
////            try
////            {
////                Assembly.LoadFrom(path);
////                return true;
////            }
////            catch (BadImageFormatException)
////            {
////                return false;
////            }
////        }

////        private bool CheckApplicationExists()
////        {
////            this.Log.LogMessage(string.Format("Checking whether Application exists: {0}", this.ApplicationName));
////            COMAdminCatalogCollection appCollection = GetApplications();
////            foreach (COMAdmin.COMAdminCatalogObject app in appCollection)
////            {
////                if (app.Name.ToString() == this.ApplicationName)
////                {
////                    this.Exists = true;
////                    return true;
////                }
////            }

////            return false;
////        }

////        private void GetPathToFramework()
////        {
////            switch (this.Runtime)
////            {
////                case "1.1":
////                    this.version = "v1.1.4322";
////                    break;
////                case "1.0":
////                    this.version = "v1.0.3705";
////                    break;
////            }

////            RegistryKey runtimeKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework");
////            if (runtimeKey != null)
////            {
////                this.pathToFramework = Convert.ToString(runtimeKey.GetValue("InstallRoot"), CultureInfo.InvariantCulture);
////                runtimeKey.Close();
////            }
////        }

////        private void UpdateComponent()
////        {
////            if (!this.CheckApplicationExists())
////            {
////                return;
////            }

////            this.Log.LogMessage(string.Format("Updating Component: {0}", this.ComponentName));
////            COMAdminCatalogCollection appCollection = GetApplications();
////            foreach (COMAdmin.COMAdminCatalogObject app in appCollection)
////            {
////                if (app.Name.ToString() == this.ApplicationName)
////                {
////                    COMAdmin.ICatalogCollection componentCollection = (COMAdmin.ICatalogCollection)appCollection.GetCollection("Components", app.Key);
////                    componentCollection.Populate();
////                    foreach (COMAdmin.COMAdminCatalogObject component in componentCollection)
////                    {
////                        if (component.Name.ToString() == this.ComponentName)
////                        {
////                            component.set_Value("ConstructorString", this.ConstructorString ?? string.Empty);
////                            component.set_Value("ConstructionEnabled", !string.IsNullOrEmpty(this.ConstructorString));
////                            componentCollection.SaveChanges();
////                            break;
////                        }
////                    }

////                    break;
////                }
////            }

////            appCollection.SaveChanges();
////        }

////        private void UpdateApplication()
////        {
////            if (!this.CheckApplicationExists())
////            {
////                return;
////            }

////            this.Log.LogMessage(String.Format(CultureInfo.InvariantCulture, "Updating: {0}", this.ApplicationName));
////            COMAdminCatalogCollection appCollection = GetApplications();
////            foreach (COMAdmin.COMAdminCatalogObject app in appCollection)
////            {
////                if (app.Name.ToString() == this.ApplicationName)
////                {
////                    if (!string.IsNullOrEmpty(this.Identity))
////                    {
////                        app.set_Value("Identity", this.Identity);
////                        app.set_Value("Password", this.UserPassword ?? string.Empty);
////                    }

////                    app.set_Value("Activation", this.activation.ToString());
////                    app.set_Value("RunForever", this.RunForever);
////                    app.set_Value("ApplicationAccessChecksEnabled", this.EnforceAccessChecks);

////                    if (!string.IsNullOrEmpty(this.ShutdownAfter))
////                    {
////                        app.set_Value("ShutdownAfter", Convert.ToInt32(this.ShutdownAfter, CultureInfo.InvariantCulture));
////                    }

////                    appCollection.SaveChanges();
////                    break;
////                }
////            }
////        }

////        private void StartApplication()
////        {
////            try
////            {
////                if (this.CheckApplicationExists())
////                {
////                    this.Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Starting Application: {0}", this.ApplicationName));
////                    COMAdmin.COMAdminCatalog f = new COMAdminCatalog();
////                    f.StartApplication(this.ApplicationName);
////                }
////            }
////            catch (Exception ex)
////            {
////                Log.LogError(string.Format(CultureInfo.InvariantCulture, "Error starting Application: {0}. Error: {1}", this.ApplicationName, ex.Message));
////            }
////        }

////        private void ShutDownApplication()
////        {
////            try
////            {
////                if (this.CheckApplicationExists())
////                {
////                    this.Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Stopping Application: {0}", this.ApplicationName));
////                    COMAdmin.COMAdminCatalog f = new COMAdminCatalog();
////                    f.ShutdownApplication(this.ApplicationName);
////                }
////            }
////            catch (Exception ex)
////            {
////                Log.LogError(string.Format(CultureInfo.InvariantCulture, "Error stopping Application: {0}. Error: {1}", this.ApplicationName, ex.Message));
////            }
////        }

////        private void RemoveComponent()
////        {
////            this.Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Removing Component: {0}", this.Path));
////            if (File.Exists(this.Path) == false)
////            {
////                this.Log.LogError(string.Format(CultureInfo.InvariantCulture, "Path not found: {0}", this.Path));
////                return;
////            }

////            if (IsValidAssemblyFile(this.Path))
////            {
////                string args = String.Format(CultureInfo.InvariantCulture, @"/quiet /u ""{0}""", this.Path);
////                this.shellWrapper = new ShellWrapper(System.IO.Path.Combine(System.IO.Path.Combine(this.pathToFramework, this.version), "regsvcs.exe"), args);
////                this.Log.LogMessage(string.Format("Executing {0} with {1}", this.shellWrapper.Executable, this.shellWrapper.Arguments));
////                if (this.shellWrapper.Execute() != 0)
////                {
////                    this.Log.LogError("Shell execute failed: " + this.shellWrapper.StandardOutput);
////                }
////            }
////            else
////            {
////                this.RemoveNonDotNetComponent();
////            }
////        }

////        private void DeleteApplication()
////        {
////            if (!this.CheckApplicationExists())
////            {
////                return;
////            }

////            this.Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Deleting Application: {0}", this.ApplicationName));

////            COMAdminCatalogCollection appCollection = GetApplications();
////            int i = 0;
////            foreach (COMAdmin.COMAdminCatalogObject cat in appCollection)
////            {
////                if (cat.Name.ToString() == this.ApplicationName)
////                {
////                    appCollection.Remove(i);
////                    appCollection.SaveChanges();
////                    break;
////                }

////                i++;
////            }
////        }

////        private void AddComponent()
////        {
////            this.Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Adding Component: {0} to Application: {1}", this.Path, this.ApplicationName));
////            if (File.Exists(this.Path) == false)
////            {
////                this.Log.LogError(string.Format(CultureInfo.InvariantCulture, "Path not found: {0}", this.Path));
////                return;
////            }

////            if (IsValidAssemblyFile(this.Path))
////            {
////                this.shellWrapper = new ShellWrapper(System.IO.Path.Combine(System.IO.Path.Combine(this.pathToFramework, this.version), "regsvcs.exe"), string.IsNullOrEmpty(this.ApplicationName) ? String.Format(CultureInfo.InvariantCulture, "/quiet {0}", this.Path) : String.Format(CultureInfo.InvariantCulture, @"/quiet {0} ""{1}""", this.Path, this.ApplicationName));
////                this.Log.LogMessage(string.Format("Executing {0} with {1}", this.shellWrapper.Executable, this.shellWrapper.Arguments));
////                if (this.shellWrapper.Execute() != 0)
////                {
////                    this.Log.LogError("Shell execute failed: " + this.shellWrapper.StandardOutput);
////                    return;
////                }
////            }
////            else
////            {
////                this.AddNonDotNetComponent();
////            }

////            this.UpdateApplication();
////        }

////        private void RemoveNonDotNetComponent()
////        {
////            this.Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Removing Component: {0} from Application: {1}", this.Path, this.ApplicationName));

////            if (!this.CheckApplicationExists())
////            {
////                return;
////            }

////            COMAdminCatalogCollection appCollection = GetApplications();
////            foreach (COMAdmin.COMAdminCatalogObject app in appCollection)
////            {
////                if (app.Name.ToString() == this.ApplicationName)
////                {
////                    COMAdmin.ICatalogCollection componentCollection = (COMAdmin.ICatalogCollection)appCollection.GetCollection("Components", app.Key);
////                    componentCollection.Populate();
////                    int i = 0;
////                    foreach (COMAdmin.COMAdminCatalogObject component in componentCollection)
////                    {
////                        if (component.Name.ToString() == this.Path)
////                        {
////                            componentCollection.Remove(i);
////                            componentCollection.SaveChanges();
////                            break;
////                        }

////                        i++;
////                    }

////                    break;
////                }
////            }

////            appCollection.SaveChanges();
////        }

////        private void AddNonDotNetComponent()
////        {
////            COMAdminCatalogCollection appCollection = GetApplications();
////            if (!this.CheckApplicationExists())
////            {
////                COMAdmin.COMAdminCatalogObject objObject = (COMAdmin.COMAdminCatalogObject) appCollection.Add();
////                objObject.set_Value("Name", this.ApplicationName);
////                objObject.set_Value("Description", this.ApplicationDescription);
////                objObject.set_Value("Activation", this.activation);
////                objObject.set_Value("Identity", this.Identity);
////                appCollection.SaveChanges();
////            }
            
////            appCollection = GetApplications();
////            foreach (COMAdmin.COMAdminCatalogObject app in appCollection)
////            {
////                if (app.Name.ToString() == this.ApplicationName)
////                {
////                    COMAdmin.ICatalogCollection componentCollection = (COMAdmin.ICatalogCollection)appCollection.GetCollection("Components", app.Key);
////                    foreach (COMAdmin.COMAdminCatalogObject component in componentCollection)
////                    {
////                        if (component.Name.ToString() == this.Path)
////                        {
////                            COMAdmin.COMAdminCatalog f = new COMAdminCatalog();
////                            f.InstallComponent(this.ApplicationName, this.Path, String.Empty, String.Empty);
////                            break;
////                        }
////                    }

////                    break;
////                }
////            }

////            appCollection.SaveChanges();
////        }
////    }
////}